*****************************************************************************
**                                                                         **
** Internal decrunch modules for Eagleplayer                               **
**                                                                         **
** Project: Eagleplayer 2.04                                               **
** Authors: Jan Blumenthal & Henryk Richter                                **
** Start  : 1993/01/09                                                     **
** $Header$                                                                **
**                                                                         **
*****************************************************************************
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program (See the included file COPYING);
** if not, write to the Free Software Foundation, Inc.,
** 675 Mass Ave, Cambridge, MA 02139, USA.
**
*****************************************************************************




;******************************************************************************
;****            Decruncher für Stonecracker 4.10 (S404 Files)              ***
;****-----------------------------------------------------------------------***
;**** call with registers: a2 = destination address                         ***
;****                      a1 = crunched data                               ***
;******************************************************************************
DecrunchSTC404
;-----------------------------------------------------------------------------
	movem.l	d0-a6,-(sp)
	move.l	File(a5),a1		;CrunchedData
	move.l	PPAdr(a5),a2		;Destination
	bsr	.decrunch
	movem.l	(sp)+,d0-a6
	rts
;------------- Uses d0-d7/a0-a6 --------------------
.decrunch:
l0:		addq	#8,a1
edDCopyableStart:
		move.l	a2,a5
		add.l	(a1)+,a2
		add.l	(a1),a1
edDCopyableStart2:
		moveq	#0,d4
		moveq	#16,d5
		movem	(a1),d2/d6/d7
		not	d4
		lea	loff6(pc),a3
		lea	llen5a(pc),a4
		moveq	#1,d0
		moveq	#-1,d3
		bra.s	ltest1

		cnop	0,8			; Use if main loop>=244 bytes

;*** Here's the start of the instruction cache

lins:		subq	#8,d7
		bpl.s	lins2
lins1:		move	d7,d1
		addq	#8,d7
		lsl.l	d7,d6
		move	-(a1),d6
		neg	d1
		lsl.l	d1,d6
		addq	#8,d7
		swap	d6
		move.b	d6,-(a2)
		swap	d6
		cmp.l	a2,a5
		dbhs	d7,lmain
		bra.s	lexma

lins2:		rol	#8,d6
		move.b	d6,-(a2)
ltest1:		cmp.l	a2,a5
		dbhs	d7,lmain
lexma		bhs.s	lexit

lmain1:		move	-(a1),d6
		moveq	#15,d7
lmain:		add	d6,d6
		bcc.s	lins

		dbf	d7,llen1
		move	-(a1),d6
		moveq	#15,d7
llen1:		add	d6,d6
		bcs.s	llen6
		moveq	#2,d1
		moveq	#4-2,d3
		dbf	d7,llen2
		move	-(a1),d6
		moveq	#15,d7
llen2:		add	d6,d6
		bcs.s	llen5
		dbf	d7,llen3
		move	-(a1),d6
		moveq	#15,d7
llen3:		add	d6,d6
		bcc.s	llen4
		moveq	#4,d1
		moveq	#8-2,d3
		lea	llen3a(pc),a6
		bra.s	lbits
llen3a:		add	d1,d3
		cmp	#15,d1
		blo.s	loff1

		moveq	#5,d1
		moveq	#14-1,d3
		lea	llen3b(pc),a6
		bra.s	lbits

llen4:		moveq	#23-2,d3
lloop:		moveq	#8,d1
llen5:		move.l	a4,a6
		bra.s	lbits
llen5a:		add	d1,d3
		not.b	d1
		dbeq	d7,loff2
		bne.s	loff2a
		bra.s	lloop

loff6:		add	d1,a0
		move.b	(a0),-(a2)
lcopy:		move.b	-(a0),-(a2)
		dbf	d3,lcopy
ltest:		cmp.l	a2,a5
		dbhs	d7,lmain
		blo.s	lmain1
lexit:		rts

llen6:		dbf	d7,llen7
		move	-(a1),d6
		moveq	#15,d7
llen7:		add	d6,d6
		addx	d0,d3
loff1:		dbf	d7,loff2
loff2a:		move	-(a1),d6
		moveq	#15,d7
loff2:		add	d6,d6
		bcs.s	loff3

		dbf	d7,loff4
		move	-(a1),d6
		moveq	#15,d7
loff4:		moveq	#9,d1
		lea	32(a2),a0
		add	d6,d6
		bcc.s	loff5
		moveq	#5,d1
		move.l	a2,a0
		bra.s	loff5
loff3:		lea	544(a2),a0
		move	d2,d1
loff5:		move.l	a3,a6

lbits:		and.l	d4,d6
		sub	d1,d7
		bpl.s	lbits2
		add	d7,d1
		lsl.l	d1,d6
		move	d7,d1
		move	-(a1),d6
		neg	d1
		add	d5,d7
lbits2:		lsl.l	d1,d6
		move.l	d6,d1
		swap	d1
		jmp	(a6)

; This part is not executed very often.  Some files may decrunch much slower
; on the 68020/68030.

llen3b:		add	d1,d3
l2ins:		subq	#8,d7
		bmi.s	l2ins1
		rol	#8,d6
		move.b	d6,-(a2)
		dbf	d3,l2ins
		bra.s	ltest

l2ins1:		move	d7,d1
		addq	#8,d7
		lsl.l	d7,d6
		move	-(a1),d6
		neg	d1
		lsl.l	d1,d6
		addq	#8,d7
		swap	d6
		move.b	d6,-(a2)
		swap	d6
		dbf	d3,l2ins
		bra	ltest
;******************************************************************************
;**** Decruncher für SoundTracker/NoiseTracker/Startrekker/Protracker-SONGS ***
;****-----------------------------------------------------------------------***
;****	a0	=	Pointer to Crunched Data			    ***
;****	a1	=	Pointer to Decrunch-Puffer			    ***
;******************************************************************************
DecrunchPack:	move.l	File(a5),a0		;CrunchedData
		move.l	PPAdr(a5),a1		;Destination
		
	;	cmp.l	#"PACK",(a0)
	;	bne.s	.Error

		addq.l	#4,a0
		move.l	(a0)+,d0		;CrunchedSize laden
		move.l	(a0)+,d1		;DecrunchedSize laden

		adda.l	d0,a0			;End of Packed File
		movea.l	d1,a2
		adda.l	a1,a2			;a2=End of DepackedFile
		move.l	-(a0),d0
.Pack1:		lsr.l	#1,d0
		bne.s	.Pack2
		bsr.s	.Pack14
.Pack2:		bcs.s	.Pack9
		moveq	#8,d1
		moveq	#1,d3
		lsr.l	#1,d0
		bne.s	.Pack3
		bsr.s	.Pack14
.Pack3:		bcs.s	.Pack11
		moveq	#3,d1
		moveq	#0,d4
.Pack4:		bsr.s	.Pack15
		move.w	d2,d3
		add.w	d4,d3
.Pack5:		moveq	#7,d1
.Pack6:		lsr.l	#1,d0
		bne.s	.Pack7
		bsr.s	.Pack14
.Pack7:		roxl.l	#1,d2
		dbra	d1,.Pack6
		move.b	d2,-(a2)
		dbra	d3,.Pack5
		bra.s	.Pack13

.Pack8:		moveq	#8,d1
		moveq	#8,d4
		bra.s	.Pack4

.Pack9:		moveq	#2,d1
		bsr.s	.Pack15
		cmp.b	#2,d2
		blt.s	.Pack10
		cmp.b	#3,d2
		beq.s	.Pack8
		moveq	#8,d1
		bsr.s	.Pack15
		move.w	d2,d3
		move.w	#8,d1
		bra.s	.Pack11

.Pack10:	moveq	#9,d1
		add.w	d2,d1
		addq.w	#2,d2
		move.w	d2,d3
.Pack11:	bsr.s	.Pack15
.Pack12:	subq.w	#1,a2
		move.b	0(a2,d2.w),(a2)
		dbra	d3,.Pack12
.Pack13:	cmpa.l	a2,a1
		blt.s	.Pack1
		rts

.Pack14:	move.l	-(a0),d0
		move.w	#$10,ccr
		roxr.l	#1,d0
		rts

.Pack15:	subq.w	#1,d1
		moveq	#0,d2
.Pack16:	lsr.l	#1,d0
		bne.s	.Pack17
		move.l	-(a0),d0
		move.w	#$10,ccr
		roxr.l	#1,d0
.Pack17:	roxl.l	#1,d2
		dbra	d1,.Pack16
		rts

*----------------------------------------------------------------------------*
*--------- Testet, ob File ein PP-File ist und entpackt werden kann ---------*
*------- a0=Fileadresse							-----*
*----------------------------------------------------------------------------*
TestAufPP:	movem.l	d1-a6,-(a7)
		moveq	#0,d0
		cmp.l	#"PP10",(a0)
		beq.s	.Ja
		cmp.l	#"PP15",(a0)
		beq.s	.Ja
		cmp.l	#"PP20",(a0)
		beq.s	.Ja
		cmp.l	#"PP2S",(a0)
		beq.s	.Ja
		tst.l	EPG_PPBase(a5)
		beq.s	.Nein
		cmp.l	#"PX20",(a0)
		beq.s	.Ja
		cmp.l	#"PX2S",(a0)
		bne.s	.Nein
.Ja:		moveq	#1,d0
.Nein:		movem.l	(a7)+,d1-a6
		tst.l	d0
		rts

	;*******************************************
	;**** Powerpacker-Datenfile Decruncher	****
	;**** Amiga-Special 7/8/92 Seite 96	****
	;**** a0=Pointer auf Crunched Files	****
	;**** d0=Länge des Crunched Files	****
	;**** a1=Pointer auf Decrunch-Puffer	****
	;*******************************************
PPDecrunch:	movem.l	d1-a6,-(a7)


	*------------ File encrypten ------------*
		move.l	File(a5),a0
		move.l	(a0),d4
		move.l	d4,-(a7)			;Achtung
		tst.l	EPG_PPBase(a5)
		beq.s	.NoCrypt
		cmp.l	#"PX20",d4
		beq.s	.Decrypt
		cmp.l	#"PX2S",d4
		bne.s	.NoCrypt

	*------------ File encrypten ------------*
.Decrypt:	moveq	#2,d6
.NextVersuch:	jsr	A5GetPassword(a5)
		move.l	EPG_PPBase(a5),a6
		lea	PasswordPuffer(a5),a0
		jsr	_LVOPPCalcCheckSum(a6)
		move.l	File(a5),a0
		cmp.w	4(a0),d0
		beq.s	.PasswordOk
		dbf	d6,.NextVersuch
		addq.l	#4,a7				;Achtung
		moveq	#EPR_Passwordfailed,d0
		bra.w	.PPEnde

.PasswordOk:	move.l	EPG_PPBase(a5),a6
		lea	PasswordPuffer(a5),a0
		jsr	_LVOPPCalcPasskey(a6)
		move.l	d0,d1
		move.l	File(a5),a0
		lea	10(a0),a0
		move.l	FileSizeNeu(a5),d0
		subq.l	#8,d0			;Kennung & Efficience
		subq.l	#6,d0			;Chksumme & Länge
		and.l	#$fffffc,d0
		jsr	_LVOPPDecrypt(a6)



	*----------- Normal entpacken -----------*
.NoCrypt:	jsr	A5WaitMouse(a5)
		move.l	PPAdr(a5),a1		;Decrunchadr
		move.l	File(a5),a0
		move.l	FileSizeNeu(a5),d0
		lea	4(a0),a2		;Efficiency laden
		cmp.b	#"X",1(a0)		;Protected ????
		bne.s	.NoEncrypt
		addq.l	#2,a2
.NoEncrypt:	move.l	a2,a3
		lea	0(a0,d0.l),a0		;Decrunchadr   holen

		move.l	EPG_PPBase(a5),d1
		beq.s	.NoLib
		move.l	d1,a6

	*------- Library-Decruncher nutzen ------*
		moveq	#4,d0
	*	tst.b	OnFlashPointer(a5)
	*	beq.s	.NoFlash
	*	moveq	#2,d0
.NoFlash:	moveq	#0,d1
		jsr	_LVOPPDecrunchBuffer(a6)
		bra.b	.Lib

	*------ Internen-Decruncher nutzen ------*
.NoLib:		bsr.w	.PPDecrunch2
.Lib:		move.l	(a7)+,d4


	*- Den verwendeten Samplemode zurücksetzen --*
		cmp.b	#"S",d4			;SampleMode
		bne.s	.NoSampleMode

	*--------- Decrypt SFCD-Formate ----------*
		move.l	PPSize(a5),d0
		move.l	PPAdr(a5),a0
		subq.l	#1,d0
		move.b	(a0)+,d1
.Schl_Crypt:	move.b	(a0),d2
		add.b	d1,d2
		move.b	d2,(a0)+
		move.b	d2,d1
		subq.l	#1,d0
		bne.s	.Schl_Crypt

		

	*-------------- Entpacken beendet --------------*
.NoSampleMode:	moveq	#0,d0
.PPEnde:	movem.l	(a7)+,d1-a6
		tst.l	d0
		rts



*----------------- eigene Decrunchroutine für Powerpacker -------------------*
.PPDecrunch2:	move.l	a1,a2
		moveq	#3,d6
		moveq	#7,d7
		moveq	#1,d5
		move.l	-(a0),d1
		tst.b	d1
		beq.s	PPLb1
		bsr.s	PPLb5
		subq.b	#1,d1
		lsr.l	d1,d5
PPLb1:		lsr.l	#8,d1
		add.l	d1,a2
PPLb2:		bsr.b	PPLb5
		bcs.b	PPLb12
		moveq	#0,d2
PPLb3:		moveq	#1,d0
		bsr.b	PPLb8
		add.w	d1,d2
		cmp.w	d6,d1
		beq.s	PPlb3
PPLb4:		moveq	#7,d0
		bsr.s	PPLb8
		move.b	d1,-(a2)
		dbf	d2,PPLb4
		cmp.l	a2,a1
		bcs.s	PPLb12
PPExit:		rts

PPLb5:		lsr.l	#1,d5
		beq.s	PPLb6
		rts

PPLb6:		move.l	-(a0),d5
		roxr.l	#1,d5
		rts

PPLb7:		subq.w	#1,d0
PPLb8:		moveq	#0,d1
PPLb9:		lsr.l	#1,d5
		beq.b	PPLb11
PPLb10:		roxl.l	#1,d1
		dbf	d0,PPlb9
		rts

PPLb11:		move.l	-(a0),d5
		roxr.l	#1,d5
		bra.s	PPLb10

PPLb12:		moveq	#1,d0
		bsr.s	PPLb8
		moveq	#0,d0
		move.b	0(a3,d1.w),d0
		move.w	d1,d2
		cmp.w	d6,d2
		bne.s	PPLb15
		bsr.s	PPLb5
		bcs.s	PPLb13
		moveq	#7,d0
PPLb13:		bsr.s	PPLb7
		move.w	d1,d3
PPLb14:		moveq	#2,d0
		bsr.s	PPLb8
		add.w	d1,d2
		cmp.w	d7,d1
		beq.s	PPLb14
		bra.s	PPLb16
PPLb15:		bsr.s	PPlb7
		move.w	d1,d3
PPLb16:		addq.w	#1,d2
PPLb17:		move.b	0(a2,d3.w),-(a2)
		dbf	d2,PPlb17
	*	tst.b	OnFlashPointer(a5)
	*	beq.s	.NoFlash
	*	move.w	a2,$dff1a6
.NoFlash:	cmp.l	a2,a1
		bcs.w	PPlb2
		rts


	;******************************
	;**** Fimp-Decruncher V1.0 ****
	;******************************
Exploding:	movem.l	d2-d5/a2-a4,-(sp)
		moveq	#0,d6
		move.l	file(a5),a0
		move.l	a0,a3
		move.l	a0,a4
		addq.l	#4,a0

	;	cmp.l	#$494d5021,(a0)+
	;	bne.s	Fimp_1e8

		add.l	(a0)+,a4
		add.l	(a0)+,a3
		move.l	a3,a2
		move.l	(a2)+,-(a0)
		move.l	(a2)+,-(a0)
		move.l	(a2)+,-(a0)
		move.l	(a2)+,d2
		move.w	(a2)+,d3
		bmi.s	Fimp_1be
		subq.l	#1,a3
Fimp_1be	lea	-$1c(sp),sp
		move.l	sp,a1
		moveq	#6,d0
Fimp_1c6	move.l	(a2)+,(a1)+
		dbra	d0,Fimp_1c6

		move.l	sp,a1
		moveq	#0,d4
Fimp_1d0	tst.l	d2
		beq.s	Fimp_1da
Fimp_1d4	move.b	-(a3),-(a4)
		subq.l	#1,d2
		bne.s	Fimp_1d4
Fimp_1da	cmp.l	a4,a0
		bcs.s	Fimp_1f2
		lea	$1c(sp),sp
		moveq	#-$1,d0
		cmp.l	a3,a0
		beq.s	Fimp_1ea
Fimp_1e8	moveq	#0,d0
Fimp_1ea	movem.l	(sp)+,d2-d5/a2-a4
		tst.l	d0
		rts

Fimp_1f2	add.b	d3,d3
		bne.s	Fimp_1fa
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_1fa	bcc.s	Fimp_260
		add.b	d3,d3
		bne.s	Fimp_204
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_204	bcc.s	Fimp_25a
		add.b	d3,d3
		bne.s	Fimp_20e
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_20e	bcc.s	Fimp_254
		add.b	d3,d3
		bne.s	Fimp_218
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_218	bcc.s	Fimp_24e
		add.b	d3,d3
		bne.s	Fimp_222
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_222	bcc.s	Fimp_22a
		move.b	-(a3),d4
		moveq	#3,d0
		bra.s	Fimp_264

Fimp_22a	add.b	d3,d3
		bne.s	Fimp_232
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_232	addx.b	d4,d4
		add.b	d3,d3
		bne.s	Fimp_23c
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_23c	addx.b	d4,d4
		add.b	d3,d3
		bne.s	Fimp_246
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_246	addx.b	d4,d4
		addq.b	#6,d4
		moveq	#3,d0
		bra.s	Fimp_264

Fimp_24e	moveq	#5,d4
		moveq	#3,d0
		bra.s	Fimp_264

Fimp_254	moveq	#4,d4
		moveq	#2,d0
		bra.s	Fimp_264

Fimp_25a	moveq	#3,d4
		moveq	#1,d0
		bra.s	Fimp_264

Fimp_260	moveq	#2,d4
		moveq	#0,d0
Fimp_264	moveq	#0,d5
		move.w	d0,d1
		add.b	d3,d3
		bne.s	Fimp_270
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_270	bcc.s	Fimp_288
		add.b	d3,d3
		bne.s	Fimp_27a
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_27a	bcc.s	Fimp_284
		move.b	Fimp_2e8(pc,d0.w),d5
		addq.b	#8,d0
		bra.s	Fimp_288

Fimp_284	moveq	#2,d5
		addq.b	#4,d0
Fimp_288	move.b	Fimp_2ec(pc,d0.w),d0
Fimp_28c	add.b	d3,d3
		bne.s	Fimp_294
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_294	addx.w	d2,d2
		subq.b	#1,d0
		bne.s	Fimp_28c
		add.w	d5,d2
		moveq	#0,d5
		move.l	d5,a2
		move.w	d1,d0
		add.b	d3,d3
		bne.s	Fimp_2aa
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_2aa	bcc.s	Fimp_2c6
		add.w	d1,d1
		add.b	d3,d3
		bne.s	Fimp_2b6
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_2b6	bcc.s	Fimp_2c0
		move.w	8(a1,d1.w),a2
		addq.b	#8,d0
		bra.s	Fimp_2c6

Fimp_2c0	move.w	0(a1,d1.w),a2
		addq.b	#4,d0
Fimp_2c6	move.b	$10(a1,d0.w),d0
Fimp_2ca	add.b	d3,d3
		bne.s	Fimp_2d2
		move.b	-(a3),d3
		addx.b	d3,d3
Fimp_2d2	addx.l	d5,d5
		subq.b	#1,d0
		bne.s	Fimp_2ca
		addq.w	#1,a2
		add.l	d5,a2
		add.l	a4,a2
Fimp_2de	move.b	-(a2),-(a4)
	*	tst.b	OnFlashPointer(a5)
	*	beq.s	.NoFlash
	*	addq.l	#1,d6
	*	move.w	d6,$dff1a6
.NoFlash	subq.b	#1,d4
		bne.s	Fimp_2de
		bra	Fimp_1d0

Fimp_2e8	dc.l	$60a0a12
Fimp_2ec	dc.l	$1010101,$2030304,$405070e



	;*****************************
	;**** LH-Decrunch-Routine ****
	;*****************************
_LVOLHDeCrunch	= -$30

	;**** Now LH-DeCrunching ****
LHDecrunch:	moveq	#1,d0
		move.l	EPG_LHBase(a5),d0
		beq.s	.Return
		move.l	d0,a6
		jsr	-$1E(a6)
		move.l	d0,LHStruckAdr(a5)		;lbL000898
		beq	.Return
		move.l	File(a5),a4
		move.l	d0,a0
		lea	12(a4),a3
		move.l	a3,(a0)
		lea	8(a4),a3
		move.l	(a3),4(a0)
		move.l	PPAdr(a5),8(a0)		;Destination
		lea	4(a4),a3
		move.l	(a3),12(a0)
		move.l	EPG_LHBase(a5),a6
		jsr	_LVOLHDeCrunch(a6)

		move.l	d0,-(a7)
		move.l	LHStruckAdr(a5),a0
		move.l	EPG_LHBase(a5),a6
		jsr	-$24(a6)


		move.l	File(a5),a0
		cmp.l	#"SFCD",(a0)
		bne.s	.NoCrypt

	*--------- Decrypt SFCD-Formate ----------*
		move.l	4(a0),d0
		move.l	PPAdr(a5),a0
		subq.l	#1,d0
		move.b	(a0)+,d1
.Crypt:		move.b	(a0),d2
		add.b	d1,d2
		move.b	d2,(a0)+
		move.b	d2,d1
		subq.l	#1,d0
		bne.s	.Crypt


.NoCrypt:	move.l	(a7)+,d0
		tst.l	d0
.Return		seq	d0
		rts



*------------------------ Verschlüsselt Byte in d0 --------------------------*
DecodeD02:	movem.l	d1-a6,-(a7)
		moveq	#0,d1
		lea	TextPuffer+100(a5),a3
		move.b	Code-(TextPuffer+100)(a3),d1
		lea	CodePara1+4-(TextPuffer+100)(a3),a1
		moveq	#3,d4
.NextCode:	moveq	#0,d3
		move.b	-(a1),d3
		rol.b	#2,d1
		move.b	d1,d2
		and.b	#3,d2
		beq.s	.Add
		subq.b	#1,d2
		beq.s	.Sub
		subq.b	#1,d2
		beq.s	.Ror

	*------ Verschlüsselung EOR -------*
		eor.b	d3,d0
		bra.b	.DbfIt
		
	*------- Verschlüsselung ROR ------*
.Ror		rol.b	d3,d0
		bra.b	.DbfIt

	*------ Verschlüsselung SUB -------*
.Sub		add.b	d3,d0
		bra.b	.DbfIt

	*------- Verschlüsselung ADD ------*
.Add		sub.b	d3,d0
.DbfIt:		dbf	d4,.NextCode
		movem.l	(a7)+,d1-a6
		rts


;-------------------------------------------------*
;- StoneCracker - v4.01 - Data decruncher
;-------------------------------------------------*
;
;inputs: a0=destination address
;	 a2=crunched data
;output: d0=0 if decrunched ok
;	 d0=-1 if not StoneCracker 'S401' data
;
;--------------	decrunch data - uses d0-d6/a0-a4
StoneDecrunch:	move.l	File(a5),a2
		move.l	PPAdr(a5),a0
		addq.l	#4,a2

		moveq	#0,d7
		moveq	#2,d5
		moveq	#15,d6

		move.l	a0,a3
		add.l	(a2)+,a3		;uncrunched length
		move.l	(a2)+,d0		;crunched length
lzd_color:	*lea	$dff1a6,a4
		*tst.b	OnFlashPointer(a5)
		*bne.s	.NoFlash
		*lea	EmptyPuffer(a5),a4	;$dff1a0,a4
.NoFlash:	move	(a2)+,d0
		lsr	#1,d6
		addx	d0,d0
		bra.s	lzd_first

lzd_ympari_mennaan_yhteen_tullaan:
		add	d0,d0
lzd_first:	bne.s	lzd_no_ovl1
		move	(a2)+,d0
	*	 move	a2,(a4)			;'let there be light!'
		addx	d0,d0
lzd_no_ovl1:	bcs.s	lzd_xcopy

lzd_byte:	moveq	#0,d3
lzd_loop6:	moveq	#0,d2

		moveq	#2,d4
lzd_l1:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d2,d2
		dbf	d4,lzd_l1

		add	d2,d3
		cmp	d6,d2
		beq.s	lzd_loop6

lzd_arsi_ja_kopi_kavi_taalla:
		moveq	#7,d4
lzd_loop7:	add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx.b	d2,d2
		dbf	d4,lzd_loop7

		move.b	d2,(a0)+
		dbf	d3,lzd_arsi_ja_kopi_kavi_taalla

		bra.s	lzd_test

lzd_apuuva:	dc.b	1,2,3,-1

lzd_xcopy:	moveq	#0,d2
		moveq	#1,d4

lzd_l3:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d2,d2
		dbf	d4,lzd_l3

		moveq	#0,d3
		moveq	#0,d1
		move.b	lzd_apuuva(pc,d2.w),d3
		bmi.s	lzd_loop4

lzd_loop3:	add	d0,d0
		bne.s	lzd_no_ovl4
		move	(a2)+,d0
		addx	d0,d0
lzd_no_ovl4:	addx	d1,d1
		dbf	d3,lzd_loop3

lzd_loop4:	moveq	#7,d4
lzd_l4:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d1,d1
		dbf	d4,lzd_l4

		cmp	d5,d2
		blo.s	lzd_naeman
		moveq	#0,d2
lzd_loop5:	moveq	#0,d3

		moveq	#2,d4
lzd_l5:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d3,d3
		dbf	d4,lzd_l5

		add.l	d3,d2
		cmp	d6,d3
		beq.s	lzd_loop5

lzd_naeman:	addq.l	#2,d2
		move.l	a0,a1
		sub	d1,a1
lzd_loop8:	move.w	d7,$dff1a2
		addq.l	#1,d7
		move.b	(a1)+,(a0)+
		subq.l	#1,d2
		bpl.s	lzd_loop8

lzd_test:	cmp.l	a3,a0
		blo	lzd_ympari_mennaan_yhteen_tullaan
Stone_Return:	moveq	#0,d0
		rts

	*---------- Checksumme der ersten Structure ----------*
Key_Chk1:	moveq	#EPKF_V1ChkSum-EPKF_V1DecodeK-1,d2
		moveq	#0,d0
.ChkSumIt:	moveq	#0,d1
		move.b	(a2)+,d1
		add.w	d1,d0
		dbf	d2,.ChkSumIt
		rts


*----------------------------------------------------------------------------*
*---------------------- Ist dieses File ein CRM-File -----------------------*
*----------------------------------------------------------------------------*
TestAufCRMFile:	movem.l	d1/d3-a6,-(a7)
		move.l	TextPuffer(a5),d0
		cmp.l	KeyCrmHelp(a5),d0	"CrM!" oder "ErM!"
		beq.s	.SizeOk
		cmp.l	#"CrM!",d0
		beq.s	.SizeOk
		move.l	EPG_CrmBase(a5),d0
		beq.s	.NoBase
		move.l	d0,a6
		move.l	a0,-(a7)
		jsr	_LVOCmCheckCrunched(a6)
		move.l	(a7)+,a0
		tst.l	d0
		beq.s	.NoBase

.SizeOk:	move.l	6(a0),d0			;Decrunchsize
		move.l	10(a0),d2			;Crunchsize
		moveq	#14,d1
		add.l	d1,d2

.NoBase:	movem.l	(a7)+,d1/d3-a6
		tst.l	d0
		rts

*----------------------------------------------------------------------------*
*----------------------- CrunchMania - Decrunchroutine ----------------------*
*----------------------------------------------------------------------------*
	*--------------- Password festlegen -----------------*
CRM_Decrunch:	moveq	#EPR_CrMNotFound,d7
		move.l	EPG_CrMBase(a5),d0
		beq.s	.Error
		move.l	d0,a6

	*------------- Password eingeben -----------*
		move.l	File(a5),a0
		cmp.b	#"c",(a0)
		bne.s	.NoProtected
		jsr	A5GetPassword(a5)

	*------------ Password festlegen -----------*
.NoProtected:	sub.l	a0,a0
		moveq	#3,d0			;cm_RemoveAll
		jsr	_LVOCMProcessPW(a6)
		lea	PasswordPuffer(a5),a0
		moveq	#1,d0				;cm_AddPW
		jsr	_LVOCMProcessPW(a6)


	*---------- CRM-Daten verschieben ----------*
		move.l	File(a5),a2			;Source
		lea	14(a2),a0
		move.l	PPAdr(a5),a1			;Dest
		jsr	_LVOCMDecrunch(a6)
.KeyFound:	moveq	#0,d7
.Error:		move.l	d7,d0
		rts


;;***** Crunch-Mania Decrunch-Routine *****
;CRM_Decrunch:	movem.l	d0-a6,-(sp)
;		move.l	File(a5),a1
;		move.l	a1,a2
;		addq.l	#6,a2
;
;		move.l	(a2)+,d1
;		move.l	(a2)+,d2
;		lea	0(a2),a3
;		cmp.l	a1,a3
;		ble.s	CRM_36
;		move.l	a1,a3
;		add.l	d1,a3
;		cmp.l	a2,a3
;		ble.s	CRM_36
;		move.l	a2,a3
;		lea	0(a1),a4
;		move.l	d2,d7
;		lsr.l	#2,d7
;		addq.l	#1,d7
;		move.l	a4,a2
;CRM_30:		move.l	(a3)+,(a4)+
;		subq.l	#1,d7
;		bne.s	CRM_30
;CRM_36:		move.l	a1,a5
;		add.l	d1,a1
;		add.l	d2,a2
;		move.w	-(a2),d0
;		move.l	-(a2),d6
;		moveq	#$10,d7
;		sub.w	d0,d7
;		lsr.l	d7,d6
;		move.w	d0,d7
;		moveq	#$10,d3
;		moveq	#0,d4
;CRM_4C:		cmp.l	a5,a1
;		ble	CRM_11E
;		bsr.s	CRM_D2
;		bcc.s	CRM_76
;		moveq	#0,d4
;CRM_58:		moveq	#8,d1
;		bsr	CRM_EA
;		move.b	d0,-(a1)
;		dbra	d4,CRM_58
;
;		bra.s	CRM_4C
;
;CRM_66:		moveq	#14,d4
;		moveq	#5,d1
;		bsr.s	CRM_D2
;		bcs.s	CRM_70
;		moveq	#14,d1
;CRM_70:		bsr.s	CRM_EA
;		add.w	d0,d4
;		bra.s	CRM_58
;
;CRM_76:		bsr.s	CRM_D2
;		bcs.s	CRM_80
;		moveq	#1,d1
;		moveq	#1,d4
;		bra.s	CRM_98
;
;CRM_80:		bsr.s	CRM_D2
;		bcs.s	CRM_8A
;		moveq	#2,d1
;		moveq	#3,d4
;		bra.s	CRM_98
;
;CRM_8A:		bsr.s	CRM_D2
;		bcs.s	CRM_94
;		moveq	#4,d1
;		moveq	#7,d4
;		bra.s	CRM_98
;
;CRM_94:		moveq	#8,d1
;		moveq	#$17,d4
;CRM_98:		bsr.s	CRM_EA
;		add.w	d0,d4
;		cmp.w	#$16,d4
;		beq.s	CRM_66
;		blt.s	CRM_A6
;		subq.w	#1,d4
;CRM_A6:		bsr.s	CRM_D2
;		bcs.s	CRM_B0
;		moveq	#9,d1
;		moveq	#$20,d2
;		bra.s	CRM_C0
;
;CRM_B0:		bsr.s	CRM_D2
;		bcs.s	CRM_BA
;		moveq	#5,d1
;		moveq	#0,d2
;		bra.s	CRM_C0
;
;CRM_BA:		moveq	#14,d1
;		move.w	#$220,d2
;CRM_C0:		bsr.s	CRM_EA
;		add.w	d2,d0
;		lea	0(a1,d0.w),a3
;CRM_C8:		move.b	-(a3),-(a1)
;		dbra	d4,CRM_C8
;
;		bra	CRM_4C
;
;CRM_D2:		subq.w	#1,d7
;		bne.s	CRM_E6
;		moveq	#$10,d7
;		move.w	d6,d0
;		lsr.l	#1,d6
;		swap	d6
;		move.w	-(a2),d6
;		swap	d6
;		lsr.w	#1,d0
;		rts
;
;CRM_E6:		lsr.l	#1,d6
;		rts
;
;CRM_EA:		move.w	d6,d0
;		lsr.l	d1,d6
;		sub.w	d1,d7
;		bgt.s	CRM_FA
;		add.w	d3,d7
;		ror.l	d7,d6
;		move.w	-(a2),d6
;		rol.l	d7,d6
;CRM_FA:		add.w	d1,d1
;		and.w	CRM_100(pc,d1.w),d0
;CRM_100:	rts
;
;		dc.w	1
;		dc.w	3
;		dc.w	7
;		dc.w	15
;		dc.w	$1F
;		dc.w	$3F
;		dc.w	$7F
;		dc.w	$FF
;		dc.w	$1FF
;		dc.w	$3FF
;		dc.w	$7FF
;		dc.w	$FFF
;		dc.w	$1FFF
;		dc.w	$3FFF
;
;CRM_11E:	movem.l	(sp)+,d0-a6
;		moveq	#0,d0
;		rts

